﻿using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using ABCat.Shared;

namespace ABCat.UI.WPF.Models
{
	public sealed class StatusBarStateViewModel : INotifyPropertyChanged
	{
		#region + Events +

		public event PropertyChangedEventHandler PropertyChanged;

		#endregion
		#region + Fields +

		private string _message;
		private int _progressBarSmallMaximum;
		private string _progressBarSmallMessage;
		private int _progressBarSmallMinimum;
		private int _progressBarSmallValue = -1;
		private int _progressBarTotalMaximum;
		private string _progressBarTotalMessage;
		private int _progressBarTotalMinimum;
		private int _progressBarTotalValue = -1;
		private readonly DelegateCommand _cancelAsyncOperationCommand;

		#endregion
		#region + Properties +

		public Action<object> CancelAsyncOperation { get; set; }
		public DelegateCommand CancelAsyncOperationCommand
		{
			get
			{
				return _cancelAsyncOperationCommand;
			}
		}

		public Visibility CancelAsyncOperationCommandVisibibility
		{
			get { return _progressBarSmallValue >= 0 || _progressBarTotalValue >= 0 ? Visibility.Visible : Visibility.Collapsed; }
		}

		public Func<object, bool> IsCanCancelAsyncOperation { get; set; }

		public string Mesage
		{
			get { return _message; }
			set
			{
				if (value == _message) return;
				_message = value;
				OnPropertyChanged();
			}
		}

		public int ProgressBarSmallMaximum
		{
			get { return _progressBarSmallMaximum; }
			set
			{
				if (Equals(_progressBarSmallMaximum, value)) return;
				_progressBarSmallMaximum = value;
				OnPropertyChanged();
			}
		}

		public string ProgressBarSmallMessage
		{
			get { return _progressBarSmallMessage; }
			set
			{
				if (Equals(_progressBarSmallMessage, value)) return;
				_progressBarSmallMessage = value;
				OnPropertyChanged();
			}
		}

		public int ProgressBarSmallMinimum
		{
			get { return _progressBarSmallMinimum; }
			set
			{
				if (Equals(_progressBarSmallMinimum, value)) return;
				_progressBarSmallMinimum = value;
				OnPropertyChanged();
			}
		}

		public int ProgressBarSmallValue
		{
			get { return _progressBarSmallValue; }
			set
			{
				if (Equals(_progressBarSmallValue, value)) return;
				_progressBarSmallValue = value;
				if (value > 0) ProgressBarSmallVisibility = Visibility.Visible;
				else ProgressBarSmallVisibility = Visibility.Collapsed;
				OnPropertyChanged();
			}
		}

		public Visibility ProgressBarSmallVisibility
		{
			get { return ProgressBarSmallValue >= 0 ? Visibility.Visible : Visibility.Collapsed; }
			set
			{
				OnPropertyChanged();
				OnPropertyChanged("CancelAsyncOperationCommandVisibibility");
			}
		}

		public int ProgressBarTotalMaximum
		{
			get { return _progressBarTotalMaximum; }
			set
			{
				if (Equals(_progressBarTotalMaximum, value)) return;
				_progressBarTotalMaximum = value;
				OnPropertyChanged();
			}
		}

		public string ProgressBarTotalMessage
		{
			get { return _progressBarTotalMessage; }
			set
			{
				if (Equals(_progressBarTotalMessage, value)) return;
				_progressBarTotalMessage = value;
				OnPropertyChanged();
			}
		}

		public int ProgressBarTotalMinimum
		{
			get { return _progressBarTotalMinimum; }
			set
			{
				if (Equals(_progressBarTotalMinimum, value)) return;
				_progressBarTotalMinimum = value;
				OnPropertyChanged();
			}
		}

		public int ProgressBarTotalValue
		{
			get { return _progressBarTotalValue; }
			set
			{
				if (Equals(_progressBarTotalValue, value)) return;
				_progressBarTotalValue = value;
				if (value > 0) ProgressBarTotalVisibility = Visibility.Visible;
				else ProgressBarTotalVisibility = Visibility.Collapsed;
				OnPropertyChanged();
			}
		}

		public Visibility ProgressBarTotalVisibility
		{
			get { return ProgressBarTotalValue >= 0 ? Visibility.Visible : Visibility.Collapsed; }
			set
			{
				OnPropertyChanged();
				OnPropertyChanged("CancelAsyncOperationCommandVisibibility");
			}
		}

		#endregion
		#region + Ctor +

		public StatusBarStateViewModel(Func<object, bool> isCanCancelAsyncOperation, Action<object> cancelAsyncOperation)
		{
			IsCanCancelAsyncOperation = isCanCancelAsyncOperation;
			CancelAsyncOperation = cancelAsyncOperation;
			_cancelAsyncOperationCommand = new DelegateCommand(CancelAsyncOperation, (obj) => IsCanCancelAsyncOperation(obj));
		}

		#endregion
		#region + Logic +

		private void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
		}

		#endregion
	}
}